From 317e8b06aec6f4cb1b935c0187d272c0878e55c7 Mon Sep 17 00:00:00 2001 From: Michael Fulbright Date: Wed, 3 Nov 1999 22:00:27 +0000 Subject: [PATCH] Further removal of bugginess in local buffering code. Handles grayscale 1999-11-03 Michael Fulbright * src/io-jpeg.c (image_load_increment): Further removal of bugginess in local buffering code. Handles grayscale jpegs correctly now. * src/io-jpeg.c (image_load_stop): Was freeing local context for jpeg library before calling jpeg_decompres_finish (). --- gdk-pixbuf/ChangeLog | 11 ++++++- gdk-pixbuf/io-jpeg.c | 73 +++++++++++++++++++++++++++++++------------- 2 files changed, 62 insertions(+), 22 deletions(-) diff --git a/gdk-pixbuf/ChangeLog b/gdk-pixbuf/ChangeLog index 3be684716d..58df066f56 100644 --- a/gdk-pixbuf/ChangeLog +++ b/gdk-pixbuf/ChangeLog @@ -1,3 +1,12 @@ +1999-11-03 Michael Fulbright + + * src/io-jpeg.c (image_load_increment): Further removal of + bugginess in local buffering code. Handles grayscale jpegs + correctly now. + + * src/io-jpeg.c (image_load_stop): Was freeing local context + for jpeg library before calling jpeg_decompres_finish (). + 1999-11-03 Jonathan Blandford * src/io-gif.c (image_load_increment): now handle arbitrary buffer @@ -45,7 +54,7 @@ 1999-11-03 Michael Fulbright - * src/io-jpg.c image_load_increment(): Fixed code which moved + * src/io-jpg.c (image_load_increment): Fixed code which moved buffer around as new data comes in to work properly. JPEG progressive loading should be working now except for grayscale JPEG's, which I will look into next. diff --git a/gdk-pixbuf/io-jpeg.c b/gdk-pixbuf/io-jpeg.c index 4f913d35e4..9d3ea3b437 100644 --- a/gdk-pixbuf/io-jpeg.c +++ b/gdk-pixbuf/io-jpeg.c @@ -27,7 +27,7 @@ /* - Progressive file loading notes (10/29/199) ... + Progressive file loading notes (11/03/1999) ... These are issues I know of and will be dealing with shortly: @@ -36,8 +36,6 @@ libjpeg. Progressive jpegs are rarer but I will add this support asap. - - gray images are not properly loaded - - error handling is not as good as it should be */ @@ -321,15 +319,15 @@ image_stop_load (gpointer data) if (context->pixbuf) gdk_pixbuf_unref (context->pixbuf); + jpeg_finish_decompress(&context->cinfo); + jpeg_destroy_decompress(&context->cinfo); + if (context->cinfo.src) { my_src_ptr src = (my_src_ptr) context->cinfo.src; g_free (src); } - jpeg_finish_decompress(&context->cinfo); - jpeg_destroy_decompress(&context->cinfo); - g_free (context); } @@ -350,6 +348,9 @@ image_load_increment (gpointer data, guchar *buf, guint size) struct jpeg_decompress_struct *cinfo; my_src_ptr src; guint num_left, num_copy; + guint last_bytes_left; + guint spinguard; + guchar *bufhd; g_return_val_if_fail (context != NULL, FALSE); g_return_val_if_fail (buf != NULL, FALSE); @@ -358,6 +359,11 @@ image_load_increment (gpointer data, guchar *buf, guint size) cinfo = &context->cinfo; + /* XXXXXXX (drmike) - loop(s) below need to be recoded now I + * have a grasp of what the flow needs to be! + */ + + /* skip over data if requested, handle unsigned int sizes cleanly */ /* only can happen if we've already called jpeg_get_header once */ if (context->src_initialized && src->skip_next) { @@ -366,31 +372,51 @@ image_load_increment (gpointer data, guchar *buf, guint size) return TRUE; } else { num_left = size - src->skip_next; + bufhd = buf + src->skip_next; src->skip_next = 0; } } else { num_left = size; + bufhd = buf; } - while (num_left > 0) { - /* copy as much data into buffer as possible */ + last_bytes_left = 0; + spinguard = 0; + while (src->pub.bytes_in_buffer != 0 || num_left != 0) { + + /* handle any data from caller we haven't processed yet */ + if (num_left > 0) { + if(src->pub.bytes_in_buffer && + src->pub.next_input_byte != src->buffer) + memmove(src->buffer, src->pub.next_input_byte, + src->pub.bytes_in_buffer); - if(src->pub.bytes_in_buffer && - src->pub.next_input_byte != src->buffer) - memmove(src->buffer, src->pub.next_input_byte, - src->pub.bytes_in_buffer); - num_copy = MIN (JPEG_PROG_BUF_SIZE - src->pub.bytes_in_buffer, - size); + num_copy = MIN (JPEG_PROG_BUF_SIZE - src->pub.bytes_in_buffer, + num_left); - if (num_copy == 0) - g_error ("Buffer overflow!"); +/* if (num_copy == 0) + g_error ("Buffer overflow!"); +*/ + memcpy(src->buffer + src->pub.bytes_in_buffer, bufhd,num_copy); + src->pub.next_input_byte = src->buffer; + src->pub.bytes_in_buffer += num_copy; + bufhd += num_copy; + num_left -= num_copy; + } else { + /* did anything change from last pass, if not return */ + if (last_bytes_left == 0) + last_bytes_left = src->pub.bytes_in_buffer; + else if (src->pub.bytes_in_buffer == last_bytes_left) + spinguard++; + else + last_bytes_left = src->pub.bytes_in_buffer; + } - memcpy(src->buffer + src->pub.bytes_in_buffer, buf, num_copy); - src->pub.next_input_byte = src->buffer; - src->pub.bytes_in_buffer += num_copy; - num_left -= num_copy; + /* should not go through twice and not pull bytes out of buf */ + if (spinguard > 2) + return TRUE; /* try to load jpeg header */ if (!context->got_header) { @@ -475,6 +501,8 @@ image_load_increment (gpointer data, guchar *buf, guint size) explode_gray_into_buf (cinfo, lines); context->dptr += nlines * context->pixbuf->art_pixbuf->rowstride; + +#undef DEBUG_JPEG_PROGRESSIVE #ifdef DEBUG_JPEG_PROGRESSIVE if (start_scanline != cinfo->output_scanline) @@ -494,7 +522,10 @@ image_load_increment (gpointer data, guchar *buf, guint size) #endif } /* did entire image */ - return TRUE; + if (cinfo->output_scanline >= cinfo->output_height) + return TRUE; + else + continue; } } -- 2.30.2